package models;

import java.security.Permissions;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Query;

import play.data.validation.Required;
import play.db.jpa.JPA;
import play.db.jpa.Model;

/**
 * Permission Entity, Used to identify and create the different permissions for
 * the different type of users of the organization
 * 
 * @author Karim Ezzat
 */
@Entity
public class Permission extends Model {
	
	/**
	 * object of the class Entities
	 */
	@ManyToOne
	public Entities entity;
	
	/**
	 * object of the class Organization
	 */
	@ManyToOne 
	public  Organization organization;
	
	/**
	 * object of the class User
	 */
	@ManyToOne 
	public  User user;

	/**
	 * the type of the user
	 */
	@Required
	public String aUserType;
	/**
	 * creating personal info
	 */
	@Required
	public boolean createInfo;
	/**
	 * deleting the profile
	 */
	@Required
	public boolean deleteProfile;
	/**
	 * deleting own ideas
	 */
	@Required
	public boolean deleteOwnIdeas;
	/**
	 * adding ideas to topics
	 */
	@Required
	public boolean addIdeasToTopic;
	/**
	 * adding ideas to entity
	 */
	@Required
	public boolean addIdeasToEntity;
	/**
	 * adding ideas to org
	 */
	@Required
	public boolean addIdeasToOrganization;
	/**
	 * creating a tag
	 */
	@Required
	public boolean createTag;
	/**
	 * adding a tag and untaging ideas
	 */
	@Required
	public boolean addTagOrUntagIdea;
	/**
	 * deleting and editing tags (that no one is using)
	 */
	@Required
	public boolean deleteOrEditTagNoOneIsUsing;
	/**
	 * reporting an idea or topic or comment
	 */
	@Required
	public boolean report;
	/**
	 * adding and deleting a comment
	 */
	@Required
	public boolean addOrDeleteComment;
	/**
	 * sharing a request or an idea
	 */
	@Required
	public boolean shareRequestOrIdea;
	/**
	 * rating a request or an idea
	 */
	@Required
	public boolean rateRequestOrIdea;
	/**
	 * editing personal information
	 */
	@Required
	public boolean editInfo;
	/**
	 * adding organizers to entity
	 */
	@Required
	public boolean addOrganizer;
	/**
	 * adding organization lead to organization
	 */
	@Required
	public boolean addOrganizationLead;
	/**
	 * block from viewing
	 */
	@Required
	public boolean blockView;
	/**
	 * block from using
	 */
	@Required
	public boolean blockUse;
	/**
	 * invite to be organizer in entity
	 */
	@Required
	public boolean inviteToBeOrganizer;
	/**
	 * invite to be idea developer in entity
	 */
	@Required
	public boolean inviteToBeIdeaDeveloper;
	/**
	 * posting a topic
	 */
	@Required
	public boolean postTopic;
	/**
	 * accepting and editing requests for new topics
	 */
	@Required
	public boolean acceptOrEditRequestForTopic;
	/**
	 * hiding topics
	 */
	@Required
	public boolean hideTopic;
	/**
	 * promoting ideas
	 */
	@Required
	public boolean promoteIdea;
	/**
	 * deleting a topic (that has no ideas)
	 */
	@Required
	public boolean deleteTopicHasNoIdeas;
	/**
	 * deleting and hiding an idea
	 */
	@Required
	public boolean deleteOrHideIdea;
	/**
	 * merging ideas
	 */
	@Required
	public boolean mergeIdeas;
	/**
	 * prioritizing ideas
	 */
	@Required
	public boolean prioritizeIdeas;
	/**
	 * confirming duplicates
	 */
	@Required
	public boolean confirmDuplicate;
	/**
	 * generating the invitations
	 */
	@Required
	public boolean generateInvitation;
	/**
	 * defining the type of the organization
	 */
	@Required
	public boolean defineOrganizationType;
	/**
	 * approving and rejecting the requests for relations
	 */
	@Required
	public boolean approveOrRejectRelationRequest;
	/**
	 * creating and editing entities
	 */
	@Required
	public boolean createOrEditEntities;
	/**
	 * deleting entities
	 */
	@Required
	public boolean deleteEntities;
	/**
	 * specifying the relations of entities, topics and tags
	 */
	@Required
	public boolean specifyRelations;
	/**
	 * creating the organization
	 */
	@Required
	public boolean createOrganization;
	/**
	 * creating and editing the organization profile
	 */
	@Required
	public boolean createOrEditOrganizationProfile;
	/**
	 * adding the preferences of the organization
	 */
	@Required
	public boolean addOrganizationPreferences;
	/**
	 * renaming and unassigning the relations of topic or tags
	 */
	@Required
	public boolean renameOrUnassignRelations;
	/**
	 * locking and unlocking entities or topics
	 */
	@Required
	public boolean lockOrUnlock;
	/**
	 * executing actions
	 */
	@Required
	public boolean execute;
	/**
	 * creating a relation
	 */
	@Required
	public boolean createRelation;
	/**
	 * requesting the name of a relation
	 */
	@Required
	public boolean requestRelationName;
	/**
	 * creating the name of a relation
	 */
	@Required
	public boolean createRelationName;

	/**
	 * The permission constructor, takes the usertype, the Organization, the User & the Entity
	 * and according to the usertype given, it calls a certain method
	 * 
	 * @param aUserType
	 * 				the type of user
	 * @param Organization
	 * 				the organization he is in
	 * @param User
	 * 				the user
	 * @param Entities
	 * 				the entity he is in, in the organization
	 * 
	 * @author Karim Ezzat
	 */
		public Permission(String aUserType, Organization organization, User user, Entities entity)
		{ 
			
			String ideaDeveloper ="ideaDeveloper" ;
			if(aUserType==ideaDeveloper){
				this.aUserType=ideaDeveloper;
			this.setIdeaDeveloper();
			}
			String organizer = "organizer";
			if(aUserType==organizer){
				this.aUserType=organizer;
			this.setOrganizer();
			}
			String organizationLead = "organizationLead";
			if(aUserType==organizationLead){
				this.aUserType=organizationLead;
			this.setOrganizationLead();
			}
			String systemAdmin = "systemAdmin";
			if(aUserType==systemAdmin){
				this.aUserType=systemAdmin;
			this.setSystemAdmin();
			}
			String blocked = "blocked";
			if(aUserType==blocked){
				this.aUserType=blocked;
			this.setBlocked();	
			}
			this.organization=organization;
			this.user=user;
			this.entity=entity;
		}
	
		/**
		 * A method that is called if the aUserType is "blocked", it defines
		 * the different booleans (actions) that the user has
		 * 
		 * @author Karim Ezzat
		 */
	public void setBlocked() {
		
		createInfo = false;
		deleteProfile = false;
		deleteOwnIdeas = false;
		addIdeasToTopic = false;
		addIdeasToEntity = false;
		addIdeasToOrganization = false;
		createTag = false;
		addTagOrUntagIdea = false;
		deleteOrEditTagNoOneIsUsing = false;
		report = false;
		addOrDeleteComment = false;
		shareRequestOrIdea = false;
		rateRequestOrIdea = false;
		editInfo = false;
		addOrganizer = false;
		addOrganizationLead = false;
		blockView = false;
		blockUse = false;
		inviteToBeOrganizer = false;
		inviteToBeIdeaDeveloper = false;
		postTopic = false;
		acceptOrEditRequestForTopic = false;
		hideTopic = false;
		promoteIdea = false;
		deleteTopicHasNoIdeas = false;
		deleteOrHideIdea = false;
		mergeIdeas = false;
		prioritizeIdeas = false;
		confirmDuplicate = false;
		generateInvitation = false;
		defineOrganizationType = false;
		approveOrRejectRelationRequest = false;
		createOrEditEntities = false;
		deleteEntities = false;
		specifyRelations = false;
		createOrganization = false;
		createOrEditOrganizationProfile = false;
		addOrganizationPreferences = false;
		renameOrUnassignRelations = false;
		lockOrUnlock = false;
		execute = false;
		createRelation = false;
		requestRelationName = false;
		createRelationName = false;
	}

	/**
	 * A method that is called if the aUserType is "systemAdmin", it defines
	 * the different booleans (actions) that the user has
	 * 
	 * @author Karim Ezzat
	 */
	public void setSystemAdmin() {
		
		createInfo = true;
		deleteProfile = true;
		deleteOwnIdeas = true;
		addIdeasToTopic = true;
		addIdeasToEntity = true;
		addIdeasToOrganization = true;
		createTag = true;
		addTagOrUntagIdea = true;
		deleteOrEditTagNoOneIsUsing = true;
		report = true;
		addOrDeleteComment = true;
		shareRequestOrIdea = true;
		rateRequestOrIdea = true;
		editInfo = true;
		addOrganizer = true;
		addOrganizationLead = true;
		blockView = true;
		blockUse = true;
		inviteToBeOrganizer = true;
		inviteToBeIdeaDeveloper = true;
		postTopic = true;
		acceptOrEditRequestForTopic = true;
		hideTopic = true;
		promoteIdea = true;
		deleteTopicHasNoIdeas = true;
		deleteOrHideIdea = true;
		mergeIdeas = true;
		prioritizeIdeas = true;
		confirmDuplicate = true;
		generateInvitation = true;
		defineOrganizationType = true;
		approveOrRejectRelationRequest = true;
		createOrEditEntities = true;
		deleteEntities = true;
		specifyRelations = true;
		createOrganization = true;
		createOrEditOrganizationProfile = true;
		addOrganizationPreferences = true;
		renameOrUnassignRelations = true;
		lockOrUnlock = true;
		execute = true;
		createRelation = true;
		requestRelationName = true;
		createRelationName = true;
	}

	/**
	 * A method that is called if the aUserType is "organizationLead", it defines
	 * the different booleans (actions) that the user has
	 * 
	 * @author Karim Ezzat
	 */
	public void setOrganizationLead() {
		createInfo = true;
		deleteProfile = true;
		deleteOwnIdeas = true;
		addIdeasToTopic = true;
		addIdeasToEntity = true;
		addIdeasToOrganization = true;
		createTag = true;
		addTagOrUntagIdea = true;
		deleteOrEditTagNoOneIsUsing = true;
		report = true;
		addOrDeleteComment = true;
		shareRequestOrIdea = true;
		rateRequestOrIdea = true;
		editInfo = true;
		addOrganizer = true;
		addOrganizationLead = false;
		blockView = true;
		blockUse = true;
		inviteToBeOrganizer = true;
		inviteToBeIdeaDeveloper = true;
		postTopic = true;
		acceptOrEditRequestForTopic = true;
		hideTopic = true;
		promoteIdea = true;
		deleteTopicHasNoIdeas = true;
		deleteOrHideIdea = true;
		mergeIdeas = true;
		prioritizeIdeas = true;
		confirmDuplicate = true;
		generateInvitation = true;
		defineOrganizationType = true;
		approveOrRejectRelationRequest = true;
		createOrEditEntities = true;
		deleteEntities = true;
		specifyRelations = true;
		createOrganization = true;
		createOrEditOrganizationProfile = true;
		addOrganizationPreferences = true;
		renameOrUnassignRelations = true;
		lockOrUnlock = true;
		execute = true;
		createRelation = true;
		requestRelationName = true;
		createRelationName = true;
		
	}

	/**
	 * A method that is called if the aUserType is "organizer", it defines
	 * the different booleans (actions) that the user has
	 * 
	 * @author Karim Ezzat
	 */
	public void setOrganizer() {
		
		createInfo = true;
		deleteProfile = true;
		deleteOwnIdeas = true;
		addIdeasToTopic = true;
		addIdeasToEntity = true;
		addIdeasToOrganization = true;
		createTag = true;
		addTagOrUntagIdea = true;
		deleteOrEditTagNoOneIsUsing = true;
		report = true;
		addOrDeleteComment = true;
		shareRequestOrIdea = true;
		rateRequestOrIdea = true;
		editInfo = true;
		addOrganizer = true;
		addOrganizationLead = false;
		blockView = true;
		blockUse = true;
		inviteToBeOrganizer = true;
		inviteToBeIdeaDeveloper = true;
		postTopic = true;
		acceptOrEditRequestForTopic = true;
		hideTopic = true;
		promoteIdea = true;
		deleteTopicHasNoIdeas = true;
		deleteOrHideIdea = true;
		mergeIdeas = true;
		prioritizeIdeas = true;
		confirmDuplicate = true;
		generateInvitation = false;
		defineOrganizationType = false;
		approveOrRejectRelationRequest = false;
		createOrEditEntities = false;
		deleteEntities = false;
		specifyRelations = false;
		createOrganization = false;
		createOrEditOrganizationProfile = false;
		addOrganizationPreferences = false;
		renameOrUnassignRelations = false;
		lockOrUnlock = false;
		execute = true;
		createRelation = true;
		requestRelationName = true;
		createRelationName = false;
	}

	/**
	 * A method that is called if the aUserType is "ideadeveloper", it defines
	 * the different booleans (actions) that the user has
	 * 
	 * @author Karim Ezzat
	 */
	public void setIdeaDeveloper(){
		createInfo = true;
		deleteProfile = true;
		deleteOwnIdeas = true;
		addIdeasToTopic = true;
		addIdeasToEntity = true;
		addIdeasToOrganization = true;
		createTag = true;
		addTagOrUntagIdea = true;
		deleteOrEditTagNoOneIsUsing = true;
		report = true;
		addOrDeleteComment = true;
		shareRequestOrIdea = true;
		rateRequestOrIdea = true;
		editInfo = true;
		addOrganizer = false;
		addOrganizationLead = false;
		blockView = false;
		blockUse = false;
		inviteToBeOrganizer = false;
		inviteToBeIdeaDeveloper = false;
		postTopic = false;
		acceptOrEditRequestForTopic = false;
		hideTopic = false;
		promoteIdea = false;
		deleteTopicHasNoIdeas = false;
		deleteOrHideIdea = false;
		mergeIdeas = false;
		prioritizeIdeas = false;
		confirmDuplicate = false;
		generateInvitation = false;
		defineOrganizationType = false;
		approveOrRejectRelationRequest = false;
		createOrEditEntities = false;
		deleteEntities = false;
		specifyRelations = false;
		createOrganization = false;
		createOrEditOrganizationProfile = false;
		addOrganizationPreferences = false;
		renameOrUnassignRelations = false;
		lockOrUnlock = false;
		execute = false;
		createRelation = false;
		requestRelationName = false;
		createRelationName = false;
	}
	
}